import Taro from '@tarojs/taro'

const ERROR = {
    10000 : '未初始化蓝牙适配器',
    10001 : '当前蓝牙适配器不可用',
    10002 : '没有找到指定设备',
    10003 : '连接失败',
    10004 : '没有找到指定服务',
    10005 : '没有找到指定特征值',
    10006 : '当前连接已断开',
    10007 : '当前特征值不支持此操作',
    10008 : '其余所有系统上报的异常',
    10009 : 'Android 系统特有，系统版本低于 4.3 不支持 BLE',
    100012 : '连接超时',
    100013 : '连接 deviceId 为空或者是格式不正确'
}

class Bluetooth {
    private _discoverying = false //是否已经开启startBluetoothDevicesDiscovery
    static _PREFIX = 'SYY-'
    private _deviceNo:string|number = ''

    private _device:{[key:string]:any; deviceId : any; serviceId : any; characteristicId : any}|null = null

    public onConnect:{():void}

    setDeviceNo(deviceNo:string|number) {
        this._deviceNo = deviceNo
    }

    closeBluetoothAdapter() { //取消监听蓝牙适配器状态变化事件
        Taro.closeBluetoothAdapter()
    }

    async openBluetoothAdapter() {
        Taro.showLoading({title : '正在连接设备'})
        try {
            let res = await Taro.openBluetoothAdapter()
            console.log('------------------- openBluetoothAdapter 成功')
            console.log(res)
            this.startBluetoothDevicesDiscovery()
        } catch (error) {
            console.log('------------------- openBluetoothAdapter 失败')
            console.log(error)
            let errCode = error.errCode
            Taro.hideLoading({
                complete() {
                    if(errCode == 10001) {
                        Taro.showModal({
                            content : '请检查是否已经打开蓝牙',
                            
                        })
                        return
                    }
                    if(errCode == 100012) {
                        Taro.showModal({
                            content : '连接超时，请重试'
                        })
                        return
                    }
        
                    Taro.showModal({
                        content : ERROR[errCode]
                    })
                }
            })

            console.log('------------------- 监控是否打开蓝牙')
            
            Taro.onBluetoothAdapterStateChange((result) => {
                if(result.available) {
                    console.log('------------------- 监控到蓝牙打开了')
                    Taro.showLoading({title : '正在连接设备'})
                    this.startBluetoothDevicesDiscovery()
                }
            })
            
        }
    }

    async startBluetoothDevicesDiscovery() { //开始搜寻附近的蓝牙外围设备
        if(this._discoverying) return

        this._discoverying = true

        try {
            let res = await Taro.startBluetoothDevicesDiscovery({allowDuplicatesKey: true})
            console.log('--------搜寻外围设备成功')
            console.log(res)


            this.onBluetoothDeviceFound() //监听发现到的设备
            
            
            
        } catch (error) {
            console.log('----------startBluetoothDevicesDiscovery 失败')
            let errCode = error.errCode
            Taro.hideLoading({
                complete() {
                    Taro.showModal({
                        content : ERROR[errCode]
                    })
                }
            })
        }
    }

    stopBluetoothDevicesDiscovery() { //停止搜下附近的蓝牙外围设备
        Taro.stopBluetoothDevicesDiscovery()
    }

    async onBluetoothDeviceFound() { //监控发现设备
        let key = Bluetooth._PREFIX + this._deviceNo
        Taro.onBluetoothDeviceFound(async (result) => {
            console.log('发现新设备')
            let devices = result.devices
            console.log(devices)
            console.log(devices[0].name)
            if(this._device == null) {
                for(let i = 0; i < devices.length; i ++) {
                    if(key == devices[i].name) { //已经匹配到
                        try {
                            this.stopBluetoothDevicesDiscovery() //停止搜索设备
                        } catch (error) {
                            
                        }
                        let deviceId = devices[i].deviceId
                        
                        try {
                            await Taro.createBLEConnection({ deviceId })
                            
                            let serviceRes = await Taro.getBLEDeviceServices({ deviceId })


                            for (let i = 0; i < serviceRes.services.length; i++) {
                                if (serviceRes.services[i].isPrimary) {
                                    let serviceId = serviceRes.services[i].uuid

                                    //操作之前先监听，保证第一时间获取数据
                                    this.onBLECharacteristicValueChange()

                                    this.getBLEDeviceCharacteristics(deviceId, serviceId)

                                    
                                    break
                                }
                            }

                        } catch (error) {
                            Taro.hideLoading({
                                complete() {
                                    Taro.showModal({
                                        content : ERROR[error.errCode]
                                    })
                                }
                            })
                        }
                        break
                    }
                }
            }

        })
    }

    onBLECharacteristicValueChange() { //监听设备特征值变化事件
        Taro.onBLECharacteristicValueChange(res => {
            console.log(res)
        })
    }

    async getBLEDeviceCharacteristics(deviceId, serviceId) { //获取蓝牙设备某个服务中所有特征值(characteristic)
        try {
            let res = await Taro.getBLEDeviceCharacteristics({
                deviceId,
                serviceId
            })
    
            for (let j = 0; j < res.characteristics.length; j ++) {
                let item = res.characteristics[j]
                if (item.properties.read) {
                    Taro.readBLECharacteristicValue({
                        deviceId,
                        serviceId,
                        characteristicId: item.uuid,
                    })
                }
    
                if (item.properties.write) {
                    this._device = {
                        deviceId,
                        serviceId,
                        characteristicId : item.uuid
                    }
                }
    
                if (item.properties.notify || item.properties.indicate) {
                    Taro.notifyBLECharacteristicValueChange({
                        deviceId,
                        serviceId,
                        characteristicId: item.uuid,
                        state: true,
                    })
                }
            }
        } catch (error) {
            let errCode = error.errCode
            Taro.hideLoading({
                complete() {
                    Taro.showModal({
                        content : ERROR[errCode]
                    })
                }
            })
        }
    }

    writeBLECharacteristicValue() { //写入数据

    }
}

export default Bluetooth